<!--
 * @message: 文件上传组件
-->
<template>
  <div style="display: inline-block;">
    <div
      class="circle-mask-panel"
      v-if="isShowPanel"
      :style="{height: pageHeight, width: pageWidth, opacity: panelOpacity}"
    >
      <div class="circle-panel" v-if="uploadFile.showProgress">
        <i-circle
          v-if="!isError && uploadFile.status !== 'finished'"
          :percent="uploadFile.percentage"
        >
          <span style="font-size:24px">{{uploadFile.percentage.toFixed(0)}}%</span>
        </i-circle>
        <i-circle
          v-if="uploadFile.status === 'finished'"
          :percent="100"
          stroke-color="#5cb85c"
        >
          <Icon type="ios-checkmark" size="60" style="color:#5cb85c"></Icon>
        </i-circle>
        <i-circle
          v-if="isError"
          :percent="uploadFile.percentage"
          stroke-color="#ff5500"
        >
        <span>
            <Icon type="ios-close" size="50" style="color:#ff5500"></Icon>
        </span>
        </i-circle>
        <div style="text-align: center;margin-top: 5px;font-size:20px">
          <span style="font-size: 14px">已使用 {{ useTime }} 秒</span>
          <br>
          {{ showText }} {{ ['.', '..', '...'][useTime % 3] }}
        </div>
      </div>
    </div>
    <Upload
      v-bind="$attrs"
      :action="uploadAction"
      ref="upload"
      :before-upload="privateUpload"
      :on-error="privateError"
      :on-exceeded-size="privateExceededSize"
      :on-format-error="privateFormatError"
      :on-success="privateSuccess"
      :headers="headers"
    >
      <slot name="btn">
         <Button
        :icon="btnIcon"
        :type="btnType"
        :style="{color: textColor}"
        :size="btnSize"
        > {{btnText}}</Button>
      </slot>
    </Upload>
  </div>
</template>

<script>
/**
   * 具体配置请参照iview上传组件
   */
import { mapGetters } from 'vuex'
import message from '../../utils/message'
import { typeOf } from '../../utils/verification'
import REQUEST_KEY from '../../config/request'
import { uuid } from '../../utils/data'

export default {
  name: 'BaseUpload',
  inheritAttrs: false,
  props: {
    // 按钮描述文字
    btnText: {
      type: String,
      default: '上传文件'
    },
    // 按钮大小
    btnSize: {
      type: String,
      default: 'default'
    },
    // 按钮图标
    btnIcon: {
      type: String,
      default: 'ios-cloud-upload-outline'
    },
    // 按钮类型
    btnType: {
      type: String,
      default: 'primary'
    },
    // 文件上传成功后回调函数
    successCallback: {
      type: Function
    },
    action: {
      type: String,
      required: true
    },
    isMessage: {
      type: Boolean,
      default: true
    },
    textColor: {
      type: String,
      default: '#fff'
    }
  },
  data () {
    return {
      pageHeight: window.innerHeight + 'px',
      pageWidth: window.innerWidth + 'px',
      panelOpacity: 0,
      uploadList: [],
      percent: 0,
      isError: false,
      isShowPanel: false,
      useTime: 0,
      loop: 0,
      headers: {
        authToken: null,
        submitKey: uuid(16, 16)
      }
    }
  },
  computed: {
    // 上传不走工具里面的请求，因此需要加前缀什么的
    ...mapGetters(['authToken']),
    uploadAction () {
      return REQUEST_KEY.requestParams.prefix + this.action
    },
    uploadFile () {
      // uploadList有文件返回最后一个，反之返回空对象
      return this.uploadList.length === 0 ? {} : this.uploadList[this.uploadList.length - 1]
    },
    showText () {
      let memoText = ''
      if (this.isError) {
        memoText = '上传失败'
      }
      if (!this.uploadFile.showProgress || this.uploadFile.percentage === 0) {
        memoText = '上传准备中'
      }
      if (this.uploadFile.showProgress && this.uploadFile.percentage < 100) {
        memoText = '上传中'
      }
      if (this.uploadFile.showProgress && this.uploadFile.percentage === 100) {
        memoText = '处理中'
      }
      if (this.uploadFile.status === 'finished') {
        memoText = '上传成功'
      }
      return memoText
    }
  },
  mounted () {
    this.privateInit()
  },
  beforeDestroy () {
    // 清除定时器
    window.clearInterval(this.loop)
  },
  methods: {
    /**
     * 可看着页面的初始（在页面created执行）
     */
    privateInit () {
      window.onresize = () => {
        this.pageHeight = window.innerHeight + 'px'
        this.pageWidth = window.innerWidth + 'px'
      }
      this.useTime = 0
      this.uploadList = this.$refs.upload.fileList
    },
    /**
     * 开始计时
     */
    startLoop () {
      this.useTime = 0
      this.loop = setInterval(() => {
        this.useTime++
      }, 1000)
    },
    /**
     * 上传之前触发
     */
    privateUpload (file) {
      this.headers.authToken = this.authToken
      this.uploadList = this.$refs.upload.fileList
      if (file.size <= 0) {
        message.message.error('不能上传空文件')
        return false
      }
      this.isError = false
      this.panelOpacity = 1
      this.isShowPanel = true
      this.startLoop()
    },
    /**
     * 上传错误时触发
     * @param error
     * @param file
     * @param fileList
     */
    privateError (error, file, fileList) {
      this.isError = true
      this.closePanel(0)
      message.message.error(error.response.data.message)
    },
    /**
     * 文件超出大小触发
     */
    privateExceededSize () {
      this.closePanel(0)
      message.message.error('文件超出大小触发')
    },
    /**
     * 文件类型错误
     */
    privateFormatError () {
      this.closePanel(0)
      message.message.error('文件类型错误')
    },
    /**
     * 上传成功之后
     * @param response
     * @param file
     * @param fileList
     */
    privateSuccess (response, file, fileList) {
      if (response[REQUEST_KEY.requestConfig.codeText] === REQUEST_KEY.requestConfig.code) {
        if (this.isMessage) {
          message.message.success(response.message)
        }
        if (typeOf(this.successCallback) === 'function') {
          this.successCallback(response, file, fileList)
        } else {
          this.$emit('publicSuccess', { response, file, fileList })
        }
        this.closePanel(500)
      } else {
        // 清除失败的文件
        const currFileList = fileList.filter(item => item.uid !== file.uid)
        this.$refs.upload.fileList = currFileList
        message.message.error(response.message)
        this.closePanel(0)
      }
    },
    /**
     * 关闭面板（延时500毫秒）
     * @param time
     */
    closePanel (time = 500) {
      if (this.loop) {
        window.clearInterval(this.loop)
      }
      setTimeout(() => {
        this.isShowPanel = false
        this.panelOpacity = 0
      }, time)
    },
    /**
     * 清空上传列表
     */
    publicClearFiles () {
      this.$refs.upload.clearFiles()
    }
  }
}

</script>

<style scoped>
  .circle-mask-panel{
    position: fixed;
    background-color: rgba(255, 255, 255, 0.8);
    top: 0;
    left: 0;
    z-index: 5000;
    opacity: 0;
    transition: opacity 0.2s;
  }
  .circle-panel{
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -60px;
    margin-top: -95px;
  }
</style>
